package com.saikuo.service.dao.impl;

import com.saikuo.service.constant.OrderStatus;
import com.saikuo.service.dao.IOrderDao;
import com.saikuo.service.model.Order;
import com.saikuo.service.model.OrderDetail;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * Created by shanchangyu on 16/10/18.
 */
@Repository
public class OrderDaoImpl extends JdbcDaoSupport implements IOrderDao {
    private static final BeanPropertyRowMapper<Order> mapper =
            new BeanPropertyRowMapper<>(Order.class);

    @Autowired
    OrderDaoImpl(DataSource dataSource) {
        setDataSource(dataSource);
    }


    private static final String CREATE_ORDER = " insert into y_order(user_id,user_coupon_id,price,postage,comments,store_code,pay_way,update_time,delivery_way,status,name,mobile,address) values (?,?,?,?,?,?,?,?,?,?,?,?,?)";

    @Override
    public Long createOrderInfo(final Order order) {
        KeyHolder keyHolder = new GeneratedKeyHolder();
        this.getJdbcTemplate().update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con)
                    throws SQLException {
                PreparedStatement ps = con.prepareStatement(CREATE_ORDER, Statement.RETURN_GENERATED_KEYS);
                ps.setInt(1, order.getUserId());
                ps.setInt(2, order.getUserCouponId());
                ps.setDouble(3, order.getPrice());
                ps.setDouble(4, order.getPostage());
                ps.setString(5, order.getComments());
                ps.setString(6, order.getStoreCode());
                ps.setInt(7, order.getPayWay());
                ps.setTimestamp(8, order.getUpdateTime());
                ps.setInt(9, order.getDeliveryWay());
                ps.setInt(10, order.getStatus());
                ps.setString(11, order.getName());
                ps.setString(12, order.getMobile());
                ps.setString(13, order.getAddress());
                return ps;
            }
        }, keyHolder);
        return keyHolder.getKey().longValue();
    }

    private static final String ADD_ORDER_DETAIL = "insert into y_order_detail(order_id,medicine_num,count) values(?,?,?)";

    @Override
    public int addOrderDetail(final Long orderId, final List<OrderDetail> orderDetails) {
        int[] count = this.getJdbcTemplate()
                .batchUpdate(
                        ADD_ORDER_DETAIL,
                        new BatchPreparedStatementSetter() {
                            public void setValues(PreparedStatement ps, int i)
                                    throws SQLException {
                                OrderDetail orderDetail = orderDetails.get(i);
                                ps.setLong(1, orderId);
                                ps.setString(2, orderDetail.getMedicineNum());
                                ps.setInt(3, orderDetail.getCount());
                            }
                            @Override
                            public int getBatchSize() {
                                return orderDetails.size();
                            }
                        });
        return count.length;
    }

    private static final String UPDATE_ORDER = " update y_order set status =?,update_time=? where order_id=?";

    @Override
    public boolean updateOrderInfo(Long orderId, int status) {
        return 1 == this.getJdbcTemplate().update(UPDATE_ORDER, new Object[]{status, new Date(), orderId});
    }

    private static final String COMPLETE_ORDER = " update y_order set status =?,pay_channel=?,update_time=? where order_id=?";

    @Override
    public boolean completeOrderInfo(Long orderId, int status, int payChannel) {
        return 1 == this.getJdbcTemplate().update(COMPLETE_ORDER, new Object[]{status, payChannel, new Date(), orderId});
    }

    private static final String GET_ORDER_INFO_BY_ORDER_ID = "select * from y_order where order_id = ?";

    @Override
    public Order getOrderByOrderId(Long orderId) {
        List<Order> result = this.getJdbcTemplate().query(GET_ORDER_INFO_BY_ORDER_ID,
                new Object[]{orderId}, mapper);
        if (CollectionUtils.isNotEmpty(result)) {
            return result.get(0);
        }
        return null;
    }

    private static final String GET_ORDER_INFO_BY_USER_ID = "select * from y_order where user_id=? ";

    @Override
    public List<Order> getOrdersByUserId(int userId, int orderStatus, int from, int limit) {
        String param = " and status=? order by update_time desc limit ?,?";
        if (orderStatus == OrderStatus.ALL.getValue()) {
            param = " and status !=? and status != " + OrderStatus.DELETE.getValue()+" order by order_id desc limit ?,?";
        }
        List<Order> result = this.getJdbcTemplate().query(GET_ORDER_INFO_BY_USER_ID + param ,
                new Object[]{userId, orderStatus, from, limit}, mapper);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result;
    }

    private static final String ORDER_EXIST = "select count(*) from y_order_complain where order_id=?";

    @Override
    public boolean orderExist(Long orderId) {
        return 1 == this.getJdbcTemplate().queryForObject(ORDER_EXIST,
                new Object[]{orderId}, Integer.class);
    }

    private static final String ADD_ORDER_COMPLAIN = "insert into  y_order_complain (order_id,user_id,phone,content) values (?,?,?,?)";

    @Override
    public boolean complainOrder(Long orderId, int userId, String phone, String content) {
        return 1 == this.getJdbcTemplate().update(ADD_ORDER_COMPLAIN, new Object[]{orderId, userId, phone, content});
    }

    private static final String GET_STORE_CODE_BY_ORDER_ID = "select store_code from y_order where order_id=?";

    @Override
    public String getStoreCodeByOrderId(Long orderId) {
        return this.getJdbcTemplate().queryForObject(GET_STORE_CODE_BY_ORDER_ID, new Object[]{orderId},String.class);
    }
}
